﻿using DoNetDrive.Core.Command;
using DoNetDrive.Core.Packet;
using Face8280WebSocketServer.Command.Models;
using Face8280WebSocketServer.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Face8280WebSocketServer.Command.Remote
{
    /// <summary>
    /// 上传固件
    /// </summary>
    public class PushSoftware : JsonCommand
    {
        string _version;
        string _user;
        string _Md5;
        FileStream _fileStream;

        SoftwareInfo _softwareInfo;

        int MaxLen = 1024 * 1024;
        long Index = 0;
        long LastIndex = 0;
        int ReadCount = 0;
        public PushSoftware(INCommandDetail cd, string version, FileStream fileStream, string user, string md5) : base(cd, null)
        {
            _fileStream = fileStream;
            _fileStream.Position = 0;
            _version = version;
            _Md5 = md5;
            _user = user;
            //  mJsonResult = (s) => _Result = new CommandResult(s);
          // cd.RestartCount = 0;
            _ProcessMax = (int)(fileStream.Length + MaxLen) / MaxLen;
        }
        /// <summary>
        /// 创建数据包
        /// </summary>
        protected override void CreatePacket()
        {
            var data = GetFielData();
            ChangeSoftwareInfo(data.Length);
            mSendObject = new { cmd = Reply, user = _user, version = _version, data = _softwareInfo };
            _Packet = new JsonPacket(JsonConvert.SerializeObject(mSendObject, setting), data, ReadCount);
            _ProcessStep = 1;
        }

        private void NextPacket()
        {
            var data = GetFielData();
            ChangeSoftwareInfo(data.Length);
            mSendObject = new { cmd = Reply, _user, version = _version, data = _softwareInfo };
            var packet = _Packet as JsonPacket;
            var sJson = JsonConvert.SerializeObject(mSendObject, setting);
            packet.SetJson(sJson);
            packet.SetData(data, ReadCount);
            _ProcessStep++;
        }

        protected override void CommandNext(INPacket readPacket)
        {
            if (readPacket is JsonPacket)
            {
                var jPck = readPacket as JsonPacket;
                var sJson = jPck.GetJson();
                if (CheckJsonResult(sJson) == true)
                {
                    if (_softwareInfo.Over == 1)
                    {
                        CommandCompleted();
                    }
                    else
                    {
                        CommandWaitResponse();
                        NextPacket();
                        CommandReady();              
                    }
                }
                else
                {
                    _Result = new CommandResult(sJson);
                    CommandCompleted();
                }
            }
        }
        public override bool CheckJsonResult(string sRetJson)
        {
            try
            {
                var json = JObject.Parse(sRetJson);
                if (json.Property("reply", StringComparison.OrdinalIgnoreCase) != null
                    && sRetJson.IndexOf(Reply, StringComparison.OrdinalIgnoreCase) > 0)
                {
                    var result = json.Property("result", StringComparison.OrdinalIgnoreCase);
                    return result.Value.ToString() == "200";
                }
            }
            catch (Exception ex)
            {
                SetException(ex);
                CommandError();
                Console.WriteLine(ex.Message);
            }
            return false;
        }

        private byte[] GetFielData()
        {
            var data = new byte[MaxLen];
            ReadCount = _fileStream.Read(data, 0, data.Length);
            if (ReadCount < MaxLen)
                _softwareInfo.Over = 1;
            LastIndex = Index + ReadCount - 1;
            return data;
        }
        /// <summary>
        /// 检查参数
        /// </summary>
        /// <param name="version"></param>
        /// <param name="featureData"></param>
        /// <param name="user"></param>
        private void CheckVal(string version, FeatureDataModel featureData, string user)
        {
            if (string.IsNullOrEmpty(user))
            {
                new Exception("缺少用户信息");
            }
            if (string.IsNullOrEmpty(version))
            {
                new Exception("缺少版本号");
            }
            if (featureData == null)
            {
                new Exception("缺少固件描述符");
            }
            //   data = featureData.BinaryData;
        }

        public void ChangeSoftwareInfo(int len)
        {
            if (_softwareInfo == null)
            {
                _softwareInfo = new SoftwareInfo
                {
                    Len = len,
                    Md5 = _Md5
                };
            }
            _softwareInfo.Range = Index + "-" + LastIndex;
            Index = LastIndex+1;
            // _softwareInfo.Over = (byte)(Index == _fileStream.Length ? 1 : 0);
        }
    }
}
